//
//
//
// LogManager.C

#include <string>
#include <sstream>
#include <iostream> 

#include <time.h>

#include "LogManager.h"
#include "BaseLogAdapter.h"


// self definition of strstream
#include "StrStream.h"

LogManager::LOGLEVELINFO LogManager::_LOG_LEVELS[] = 
{
	{TRACE,     "   TRACE"},
	{INFO,      "    INFO"},
	{DEBUG,     "   DEBUG"},
	{WARNING,   " WARNING"},
	{ERROR,     "   ERROR"},
	{CRITICAL,  "CRITICAL"},
};

Mutex LogManager::_instanceMutex;
LogManager* LogManager::_instance = NULL;

LogManager* LogManager::Instance(void)
{
	if(NULL == _instance)
	{
		_instanceMutex.Lock();
		if(NULL == _instance)
		{
			_instance = new LogManager();
		}
		_instanceMutex.UnLock();
	}
	return _instance;
}

void LogManager::Destroy(void)
{
	;
}

LogManager::LogManager() : _adapterType(0) , _level (ERROR){};
LogManager::~LogManager(){};

//
// Adapter register to the manager class
void LogManager::Register(BaseLogAdapter* pAdapter)
{
	//
	// Note: this function was called in adapters construtor
	//		 So, you should never called adapter functions before
	//		 the adapter was successfuly constructed.
	_adapterVec.push_back(pAdapter);
}

//
//
// Set used adapter type
void LogManager::UseAdapter(U32 adapterType)
{
	_adapterType = adapterType;
}

// Get used adapter type
U32 LogManager::UseAdapter(void)
{
	return _adapterType;
}

void LogManager::Log(LOG_LEVEL level, const std::string& info)
{
	if(level < _level)
		return;

	_writeMutex.Lock();

	Util::StrStream stream;

	stream << "["
		<< GetStrTime("%F %H:%M:%S")
		<< "."
		<< Tid2Str()
		<< "] ["
		<< LogManager::_LOG_LEVELS[level].info
		<< "] "
		<< info
		<< "\n";

	for(std::vector<BaseLogAdapter*>::iterator it = _adapterVec.begin();
			it != _adapterVec.end();
			it++)
	{
		if((*it)->AdapterType() & _adapterType)
			(*it)->Log(stream.Str());
	}
	_writeMutex.UnLock();
}

void LogManager::Flush(void)
{
	for(std::vector<BaseLogAdapter*>::iterator it = _adapterVec.begin();
			it != _adapterVec.end();
			it++)
	{
		if((*it)->AdapterType() & _adapterType)
			(*it)->Flush();
	}
}

void LogManager::LogLevel(LOG_LEVEL level)
{
	_level = level;
}	

LogManager::LOG_LEVEL LogManager::LogLevel()
{
	return _level;
}

std::string LogManager::GetStrTime(const std::string& fmt)
{
	time_t time_t_now;
	time(&time_t_now);
	struct tm* now = localtime(&time_t_now);
	char szBuf[64];
	memset(szBuf, 0, sizeof(szBuf));

	strftime(szBuf, sizeof(szBuf) - 1, fmt.c_str(), now);
	return std::string(szBuf);
}

std::string LogManager::Tid2Str(void)
{
	pthread_t tid = pthread_self();
	char szBuf[64];
	memset(szBuf, 0, sizeof(szBuf));
	sprintf(szBuf, "%04d", tid);

	return std::string(szBuf);
}


//
//
// Get adapter from adapter vector according to adapter type
BaseLogAdapter* LogManager::GetAdapter(ADAPTER_TYPE _type)
{
	for(std::vector<BaseLogAdapter*>::iterator it = _adapterVec.begin();
			it != _adapterVec.end();
			it++)
	{
		if((*it)->AdapterType() == _type)
			return dynamic_cast<BaseLogAdapter*>(*it);
	}
	return NULL;
}

void LogManager::Close()
{
	for(std::vector<BaseLogAdapter*>::iterator it = _adapterVec.begin();
			it != _adapterVec.end();
			it++)
	{
		if((*it)->AdapterType() & _adapterType)
			(*it)->Close();
	}
}
